import os
import json
import logging
import shutil
import subprocess
import traceback

from django.conf import settings
from celery import shared_task

from plugin.models import PluginInstallRecord
from system.models import DeployRequest, Menu
from libs.enums import PluginInstallState


@shared_task
def install_plugin(record_id):
    instance = PluginInstallRecord.objects.filter(id=record_id).first()
    if not instance:
        return
    try:
        instance.state = PluginInstallState.INSTALLING.value
        instance.save()
        plugin_dir = f'{settings.PLUGIN_REPO_DIR}/{instance.key}'
        if os.path.exists(plugin_dir):
            shutil.rmtree(plugin_dir)
        clone_command = ['git', 'clone', instance.git_url, plugin_dir]
        subprocess.run(clone_command, check=True)
        instance.state = PluginInstallState.INSTALLED.value
        instance.save()
        menu_json_file = os.path.join(plugin_dir, 'menu.json')
        if os.path.exists(menu_json_file):
            menus = json.load(open(menu_json_file))
            for menu in menus:
                menu['parent_id'] = 29
                menu['orderNo'] = 900
                Menu.objects.create(**menu)

        DeployRequest.objects.create()
    except Exception:
        logging.getLogger().warning(f'Clone扩展[{instance.key}]失败，异常信息：{traceback.format_exc()}')
        instance.state = PluginInstallState.INSTALL_FAILED.value
        instance.save()


@shared_task
def uninstall_plugin(record_id):
    instance = PluginInstallRecord.objects.filter(id=record_id).first()
    if not instance:
        return
    try:
        plugin_dir = f'{settings.PLUGIN_REPO_DIR}/{instance.key}'
        menu_json_file = os.path.join(plugin_dir, 'menu.json')
        if os.path.exists(menu_json_file):
            menus = json.load(open(menu_json_file))
            for menu in menus:
                Menu.objects.filter(name=menu.get('name')).delete()
        if os.path.exists(plugin_dir):
            shutil.rmtree(plugin_dir)
        instance.delete()
        DeployRequest.objects.create()
    except Exception:
        logging.getLogger().warning(f'卸载扩展[{instance.key}]失败，异常信息：{traceback.format_exc()}')
        instance.state = PluginInstallState.UNINSTALL_FAILED.value
        instance.save()
